
package com.zyh.util.safeutil;




import com.zyh.dao.KeyMapper;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;


/**
 * 报文加解密算法
 * @author luocj
 * @date 2020/5/18
 */
public class DESedeUtil {

/**
     * 密钥算法
     */

    private static final String KEY_ALGORITHM = "DESede";

    @Autowired
    private KeyMapper keyMapper;
/**
     * 加密/解密算法 / 工作模式 / 填充方式
     * Java 6支持PKCS5Padding填充方式
     * Bouncy Castle支持PKCS7Padding填充方式
     */

    private static final String CIPHER_ALGORITHM = "DESede/ECB/PKCS5Padding";





/**
     * @Description: 生成密钥, 返回168位的密钥
     * @return
     * @throws Exception
     */

    public static String generateKey() throws Exception {
        //实例化密钥生成器
        KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
        //DESede 要求密钥长度为 112位或168位
        kg.init(168);
        //生成密钥
        SecretKey secretKey = kg.generateKey();
        //获得密钥的字符串形式
        return Base64.encodeBase64String(secretKey.getEncoded());
    }

 /* public  String decryptInfo(String encryptStr){
    String key=keyMapper.querykey();
      System.out.println("====key==="+key);
       String resource ="";
    try {
        resource = decrypt(encryptStr, key);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return resource;
}*/



/**
     * @Description: DES进行加密
     * @param source 待加密的原字符串
     * @param key  加密时使用的 密钥
     * @return   返回经过base64编码的字符串
     * @throws Exception
     */

    public static String encrypt(String source, String key) throws Exception {
        byte[] sourceBytes = source.getBytes("UTF-8");
        byte[] keyBytes = Base64.decodeBase64(key);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE,new SecretKeySpec(keyBytes, KEY_ALGORITHM));
        byte[] decrypted = cipher.doFinal(sourceBytes);
        return Base64.encodeBase64String(decrypted);
    }




/**
     * @Description:  DES解密
     * @param encryptStr  DES加密后的再经过base64编码的密文
     * @param key  加密使用的密钥
     * @return  返回 utf-8 编码的明文
     * @throws Exception
     */

    public static String decrypt(String encryptStr, String key) throws Exception {
        byte[] sourceBytes = Base64.decodeBase64(encryptStr);
        byte[] keyBytes = Base64.decodeBase64(key);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE,new SecretKeySpec(keyBytes, KEY_ALGORITHM));
        byte[] decoded = cipher.doFinal(sourceBytes);
        return new String(decoded, "UTF-8");
    }



/**
     * @Description: DES进行加密
     * @param keybyte 加密时使用的 密钥
     * @param src  待加密的原字符串
     * @return
     * @throws Exception
     */

    public static byte[] encryptDESMode(byte[] keybyte, byte[] src) {
        try {
            //生成密钥
            SecretKey deskey = new SecretKeySpec(keybyte, "DES");
            //加密
            Cipher c1 = Cipher.getInstance("DES");
            c1.init(Cipher.ENCRYPT_MODE, deskey);
            return c1.doFinal(src);
        } catch (java.security.NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException e2) {
            e2.printStackTrace();
        } catch (Exception e3) {
            e3.printStackTrace();
        }
        return null;
    }



    //3DES解密
    public static byte[] decryptDESMode(byte[] keybyte, byte[] src) {

        try {
            //生成密钥
            SecretKey deskey = new SecretKeySpec(keybyte,"DES");
            //解密
            Cipher c1 = Cipher.getInstance("DES");
            c1.init(Cipher.DECRYPT_MODE,deskey);
            return c1.doFinal(src);
        } catch (java.security.NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException e2) {
            e2.printStackTrace();
        } catch (Exception e3) {
            e3.printStackTrace();
        }
        return null;
    }

    // test
    public static void main(String[] args) {
        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<Message>\n" +
                "    <Head>\n" +
                "        <serialNo>200508094432</serialNo>\n" +
                "        <reqTime>20200508094432</reqTime>\n" +
                "        <bsnCode>QRCB002</bsnCode>?\n" +
                "        <CifNo>998202000052582</CifNo>\n" +
                "    </Head>\n" +
                "    <Body>\n" +
                "        <PayerAcNo>2920054414205000010083</PayerAcNo>\n" +
                "        <BeginDate>20190901\n" +
                "        </BeginDate>\n" +
                "        <EndDate>20190922</EndDate>\n" +
                "        <StartKey/>\n" +
                "        <EndKey/>\n" +
                "    </Body>\n" +
                "</Message>";
        try {
            // 生成秘钥
            String key = generateKey();
            System.out.println("秘钥："+key);

            // 加密
            String encryptStr = encrypt(xml, key);

            System.out.println("密文："+ encryptStr);
            // 解密
            String resource = decrypt(encryptStr, key);
            System.out.println("明文："+ resource);


        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

